﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Assets.Script.Config;
using PathologicalGames;

public class SlgBattleMgr : MonoBehaviourSingleton<SlgBattleMgr>
{
    public bool m_bEditorProp = true;

    public string modelType = "_3D";
    public enum SoldierRenderType
    {
        Model,
        Spine,
    };
    public SoldierRenderType m_eRenderType = SoldierRenderType.Model;

    //数据
    List<SoldierVo> lis_Soldier;
    Dictionary<int, List<SoldierVo>> dic_Troop;
    List<HeroVo> lis_Hero;
    List<DoBuff> lis_DoBuff;
    List<DoBuff> lis_LeftDoBuff;
    List<DoBuff> lis_RightDoBuff;
    private int bufIndex;

    //实体
    Dictionary<int, SlgEntityTroop> m_DicTroops;
    List<SlgEntityTroop> m_lisTroops;
    Dictionary<int, SlgEntityHero> m_DicHeros;

    //是否初始化好了
    private bool m_bInit = false;

    //战损的数据
    Dictionary<int, List<TroopDmg>> m_DicDmg;
    private int m_iLeftMaxHp;
    private int m_iLeftHp;
    private int m_iRightMaxHp;
    private int m_iRightHp;
    private int m_fDmgNum = 0;

    //摄像机相关
    Transform m_pLeftCameraParent;
    Transform m_pRightCameraParent;
    CameraMoveComp m_pLCMoveComp;
    CameraMoveComp m_pRCMoveComp;
    Camera m_pLeftCamera;
    Camera m_pRightCamera;
    Camera m_pMainCamera;
    private float m_fCameraDis;

    public Vector3 offset = Vector3.zero;

    public void Init(List<SoldierVo> soldiers,List<HeroVo> heros,Action funcLoadDone)
    {
        m_fSpeed = 1;
        SlgBattleProperty.CreateInstance(true);
        BattleEffectMgr.Instance.Init(HeroBattleStage.BattleBigType.Slg);

        m_funcLoadDone = funcLoadDone;
        dic_Troop = new Dictionary<int, List<SoldierVo>>();
        m_DicTroops = new Dictionary<int, SlgEntityTroop>();
        m_DicHeros = new Dictionary<int, SlgEntityHero>();
        m_lisTroops = new List<SlgEntityTroop>();
        lis_DoBuff = new List<DoBuff>()
        {
            new DoBuff() {doPos = 1,skillId = 100101,bufs = new Dictionary<int, BufVo>()
            {
                {4,new BufVo() {defPos = 4,bufIds = new List<int>() { 1001021 , 1001011 } } },
                {5,new BufVo() {defPos = 5,bufIds = new List<int>() { 1001021 , 1001011 } } },
                {6,new BufVo() {defPos = 6,bufIds = new List<int>() { 1001021 , 1001011 } } },
            } },
            new DoBuff() {doPos = 2,skillId = 100101,bufs = new Dictionary<int, BufVo>()
            {
                {4,new BufVo() {defPos = 4,bufIds = new List<int>() { 1001021 , 1001011 } } },
                {5,new BufVo() {defPos = 5,bufIds = new List<int>() { 1001021 , 1001011 } } },
                {6,new BufVo() {defPos = 6,bufIds = new List<int>() { 1001021 , 1001011 } } },
            } },
            new DoBuff() {doPos = 3,skillId = 100101,bufs = new Dictionary<int, BufVo>()
            {
                {4,new BufVo() {defPos = 4,bufIds = new List<int>() { 1001021 , 1001011 } } },
                {5,new BufVo() {defPos = 5,bufIds = new List<int>() { 1001021 , 1001011 } } },
                {6,new BufVo() {defPos = 6,bufIds = new List<int>() { 1001021 , 1001011 } } },
            } },
            new DoBuff() {doPos = 21,skillId = 100101,bufs = new Dictionary<int, BufVo>()
            {
                {4,new BufVo() {defPos = 24,bufIds = new List<int>() { 1001021 , 1001011 } } },
                {5,new BufVo() {defPos = 25,bufIds = new List<int>() { 1001021 , 1001011 } } },
                {6,new BufVo() {defPos = 26,bufIds = new List<int>() { 1001021 , 1001011 } } },
            } }
        };
        lis_LeftDoBuff = new List<DoBuff>();
        lis_RightDoBuff = new List<DoBuff>();
        for (int i = 0; i < lis_DoBuff.Count; i++)
        {
            if(lis_DoBuff[i].doPos < SlgFightDef.c_iHeroIndexStep)
            {
                lis_LeftDoBuff.Add(lis_DoBuff[i]);
            }
            else
            {
                lis_RightDoBuff.Add(lis_DoBuff[i]);
            }
        }

        lis_Soldier = soldiers;
        lis_Hero = heros;
        m_iSpineRes = m_iNotReadyLoad;
        m_iModelRes = m_iNotReadyLoad;
        m_iEffectRes = m_iNotReadyLoad;

        LoadSpine();
        LoadModel();
        LoadEffect();
        InitCamera();
        m_bInit = true;
    }

    public void Reload()
    {
        m_fSpeed = 1;
        DelAllTimer();
        DelHero();
        DelTroop();
        dic_Troop = new Dictionary<int, List<SoldierVo>>();
        m_DicTroops = new Dictionary<int, SlgEntityTroop>();
        m_DicHeros = new Dictionary<int, SlgEntityHero>();
        m_lisTroops = new List<SlgEntityTroop>();
        InitCamera();
        CreateHero();
        CreateTroop();
        InitDmg();
    }

    public void StartFight()
    {
        HeroBattleLua.C2Lua_FreshSlgHp(true, m_iLeftHp, 1);
        HeroBattleLua.C2Lua_FreshSlgHp(false, m_iRightHp, 1);
    }

    //根据 战斗前-战斗后 的死亡信息 平均分配下死亡个数
    private void InitDmg()
    {
        m_DicDmg = new Dictionary<int, List<TroopDmg>>();
        int leftTroopNum = 0;
        int rightTroopNum = 0;
        m_iLeftHp = 0;
        m_iRightHp = 0;
        foreach (var item in m_DicTroops)
        {
            if (item.Value.m_bLeft)
            {
                leftTroopNum++;
                m_iLeftHp += item.Value.GetTroopHp();
            }
            else
            {
                rightTroopNum++;
                m_iRightHp += item.Value.GetTroopHp();
            }
        }
        m_iLeftMaxHp = m_iLeftHp;
        m_iRightMaxHp = m_iRightHp;
        SlgEntityTroop atk;
        foreach (var item in m_DicTroops)
        {
            atk = item.Value;
            foreach (var def in m_DicTroops)
            {
                if(atk.m_bLeft != def.Value.m_bLeft)
                {
                    if (!m_DicDmg.ContainsKey(atk.Pos))
                        m_DicDmg.Add(atk.Pos, new List<TroopDmg>());

                    TroopDmg dmg = new TroopDmg();
                    dmg.attackTroopId = atk.Pos;
                    dmg.defTroopId = def.Value.Pos;
                    dmg.dmg = def.Value.GetTroopDmg() / (def.Value.m_bLeft ? rightTroopNum : leftTroopNum);
                    dmg.done = false;
                    m_DicDmg[atk.Pos].Add(dmg);
                    if (atk.m_bLeft)
                    {
                        m_fDmgNum++;
                    }
                }
            }
        }
    }
    //部队有人受到伤害
    public void HpChange(bool bLeft,int value)
    {
        //Debug.LogFormat("{0}  扣多少血", value);
        if (bLeft)
        {
            m_iLeftHp += value;
            if (m_iLeftHp <= 0)
                m_iLeftHp = 0;

            HeroBattleLua.C2Lua_FreshSlgHp(bLeft, m_iLeftHp, (float)m_iLeftHp / (float)m_iLeftMaxHp);
        }
        else
        {
            m_iRightHp += value;
            if (m_iRightHp <= 0)
                m_iRightHp = 0;

            HeroBattleLua.C2Lua_FreshSlgHp(bLeft, m_iRightHp, (float)m_iRightHp / (float)m_iRightMaxHp);
        }
    }


    //创建英雄
    private void CreateHero()
    {
        for (int i = 0; i < lis_Hero.Count; i++)
        {
            SlgEntityHero hero = BattleEntityFactory.Instance.CreateBtEntity<SlgEntityHero>() as SlgEntityHero;
            hero.OnCreate(lis_Hero[i], m_DicSpines[lis_Hero[i].model], 
                SlgFightUtil.GetHeroPos(GetSideTroopPoss(!lis_Hero[i].m_bFilp),!lis_Hero[i].m_bFilp, GetSideHeroPoss(!lis_Hero[i].m_bFilp), lis_Hero[i].index)
                );
            m_DicHeros.Add(lis_Hero[i].index, hero);
        }
    }
    private void DelHero()
    {
        foreach (var item in m_DicHeros.Values)
        {
            BattleEntityFactory.Instance.DestroyEntity(item.Id);
        }
    }

    //创建部队
    private void CreateTroop()
    {
        for (int i = 0; i < lis_Soldier.Count; i++)
        {
            if (!dic_Troop.ContainsKey(lis_Soldier[i].pos))
            {
                dic_Troop.Add(lis_Soldier[i].pos, new List<SoldierVo>());
            }
            dic_Troop[lis_Soldier[i].pos].Add(lis_Soldier[i]);
        }

        foreach (var item in dic_Troop)
        {
            SlgEntityTroop troop = BattleEntityFactory.Instance.CreateBtEntity<SlgEntityTroop>() as SlgEntityTroop;
            troop.OnCreate(item.Key, item.Value);
            m_DicTroops.Add(item.Key, troop);
            m_lisTroops.Add(troop);
        }
    }

    private void DelTroop()
    {
        foreach (var item in m_DicTroops.Values)
        {
            List<SlgEntitySoldier> child = item.GetAllSoldier();
            for (int i = 0; i < child.Count; i++)
            {
                BattleEntityFactory.Instance.DestroyEntity(child[i].Id);
            }
            BattleEntityFactory.Instance.DestroyEntity(item.Id);
        }
    }

    public void AllTroopMove()
    {
        foreach (var item in m_DicTroops.Values)
        {
            item.ChangeState(SlgTroopState.c_sTroop_Move);
        }
    }
    public void AllTroopAtk()
    {
        foreach (var item in m_DicTroops.Values)
        {
            item.RandomDoAttack();
        }
    }
    public void AllTroopIdle()
    {
        foreach (var item in m_DicTroops.Values)
        {
            item.ChangeState(SlgTroopState.c_sTroop_Idle);
        }
    }

    #region 摄像机相关的逻辑
    private enum Flow
    {
        ReviewTroops = 1,       //检阅士兵
        DoBufSkill = 2,         //英雄放Buf
        CenterUIAnimation = 3,  //开战的UI动画
        ShooterAtk = 4,         //远程射箭
        Charge = 5,             //冲锋
        Retreat = 6,            //撤退
        Over = 7,
    }
    private Flow m_FlowState;
    private bool m_bCharge = false;
    private bool m_bFused = false;
    private bool m_bFuse2Split = true;
    private bool m_bLeftWin = true;
    private List<SlgEntityTroop> m_lisLeftChargeTroops;
    private float m_fLeftUpPass = 0;
    private float m_fLeftDownPass = 0;
    private List<SlgEntityTroop> m_lisRightChargeTroops;
    private float m_fRightUpPass = 0;
    private bool allShootFinish = false;
    private List<SlgEntityTroop> m_lisShootingTroops;
    private List<SlgEntityTroop> m_lisDefShootTroops;
    private double m_fNextArrowRainTime = 0;
    private float m_fArrowRainGap = 1;
    private bool m_bLeftCameraInLeft = true;
    private List<SlgEntityTroop> m_lisShortRangeTroops;
    private bool m_bAllShortRangeDead = true;
    private Vector3 m_v3AddCameraPos;
    private int m_iFlyToCameraNum = 0;

    //摄像机部分初始化
    private void InitCamera()
    {
        m_bCharge = false;
        m_bFused = false;
        m_bFuse2Split = true;
        m_bLeftCameraInLeft = true;
        allShootFinish = false;
        m_fNextArrowRainTime = 0;
        m_iFlyToCameraNum = 0;
        m_bAllShortRangeDead = true;
        m_v3AddCameraPos = Vector3.zero;
        Transform cameraRoot = GameObject.Find("CameraRoot").transform;
        m_pLeftCamera = cameraRoot.Find("LeftCameraParent/LeftCamera").GetComponent<Camera>();
        m_pLeftCameraParent = cameraRoot.Find("LeftCameraParent");
        m_pLCMoveComp = new CameraMoveComp(m_pLeftCameraParent, null);

        m_pRightCamera = cameraRoot.Find("RightCameraParent/RightCamera").GetComponent<Camera>();
        m_pRightCameraParent = cameraRoot.Find("RightCameraParent");
        m_pRCMoveComp = new CameraMoveComp(m_pRightCameraParent, null);

        m_pMainCamera = cameraRoot.Find("CenterCamera").GetComponent<Camera>();
        m_fCameraDis = m_pLeftCamera.orthographicSize * m_pLeftCamera.aspect + m_pRightCamera.orthographicSize * m_pRightCamera.aspect;
        m_pLeftCameraParent.gameObject.SetActive(true);
        m_pRightCameraParent.gameObject.SetActive(true);
        m_pLeftCamera.gameObject.SetActive(true);
        m_pRightCamera.gameObject.SetActive(true);
        m_pMainCamera.gameObject.SetActive(false);
        m_lisLeftChargeTroops = new List<SlgEntityTroop>();
        m_lisRightChargeTroops = new List<SlgEntityTroop>();
        m_lisShootingTroops = new List<SlgEntityTroop>();
        m_lisDefShootTroops = new List<SlgEntityTroop>();
        m_lisShortRangeTroops = new List<SlgEntityTroop>();
        m_lisShortRangeTroops.AddRange(GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, true));
        m_lisShortRangeTroops.AddRange(GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, false));
        m_pLeftCameraParent.position = ConvertTroop2Camera(GetTroopSidePos(true, true));
        m_pRightCameraParent.position = ConvertTroop2Camera(GetTroopSidePos(false, false));

        m_pLeftCameraParent.transform.localEulerAngles = SlgFightDef.FCameraAngle;
        m_pRightCameraParent.transform.localEulerAngles = SlgFightDef.FCameraAngle;
        m_pMainCamera.transform.localEulerAngles = SlgFightDef.FCameraAngle;
    }
    private void OnUpdateCameraPart(float deltaTime)
    {
        m_pLCMoveComp.OnUpdate(deltaTime);
        m_pRCMoveComp.OnUpdate(deltaTime);
        if(m_FlowState == Flow.Charge && m_bCharge)
        {
            if (m_pLeftCameraParent.gameObject.activeSelf && m_lisLeftChargeTroops.Count >0)
            {
                m_fLeftUpPass += m_fSpeed * Time.deltaTime;
                if (m_fLeftUpPass < SlgFightDef.FUpCameraDuration)
                {
                    m_v3AddCameraPos += -m_pLeftCameraParent.transform.forward.normalized * (m_fSpeed * Time.deltaTime) * (SlgFightDef.FCameraUpDis / SlgFightDef.FUpCameraDuration);
                }
                //m_pLeftCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(m_lisLeftChargeTroops));
                m_pLCMoveComp.UniformMove(10, ConvertTroop2Camera(GetTroopsCenter(m_lisLeftChargeTroops)));
            }
            if (m_pRightCameraParent.gameObject.activeSelf && m_lisRightChargeTroops.Count>0)
            {
                //m_pRightCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(m_lisRightChargeTroops));
                m_pRCMoveComp.UniformMove(10, ConvertTroop2Camera(GetTroopsCenter(m_lisRightChargeTroops)));
            }
            if(m_pLeftCameraParent.gameObject.activeSelf && m_lisLeftChargeTroops.Count > 0)
            {
                if(m_fLeftDownPass <= 0)
                {
                    if (Mathf.Abs(m_pLeftCameraParent.transform.position.x -
                    GetTroopSidePos(false, true, GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow, SlgFightDef.c_iArmyType_Tank }, false)).x)
                    <= SlgFightDef.FChargeBtweenShooter)
                    {
                        m_fLeftDownPass += m_fSpeed * Time.deltaTime;
                        if (m_fLeftDownPass < SlgFightDef.FDownCameraDuration)
                        {
                            m_v3AddCameraPos += m_pLeftCameraParent.transform.forward.normalized * (m_fSpeed * Time.deltaTime) * (SlgFightDef.FCameraDownDis / SlgFightDef.FDownCameraDuration);
                        }
                    }
                }
                else
                {
                    m_fLeftDownPass += m_fSpeed * Time.deltaTime;
                    if (m_fLeftDownPass < SlgFightDef.FDownCameraDuration)
                    {
                        m_v3AddCameraPos += m_pLeftCameraParent.transform.forward.normalized * (m_fSpeed * Time.deltaTime) * (SlgFightDef.FCameraDownDis / SlgFightDef.FDownCameraDuration);
                    }
                }
            }


            CheckTroopImpact();
            CheckCameraFuse();

            if (m_pLeftCameraParent.transform.position.x >= GetChargeStopPos(false).x)
            {
                m_lisLeftChargeTroops.Clear();
                m_pLCMoveComp.StopMove();
                if(m_pRCMoveComp.m_eType == MoveComp.moveType.Stop)
                {
                    //StepEnterOver();
                    StepEnterRetreat();
                }
            }



            if (m_pRightCameraParent.transform.position.x <= GetChargeStopPos(true).x)
            {
                m_lisRightChargeTroops.Clear();
                m_pRCMoveComp.StopMove();
                if (m_pLCMoveComp.m_eType == MoveComp.moveType.Stop)
                {
                    //StepEnterOver();
                    StepEnterRetreat();
                }
            }
            if (!m_bFused)
            {
                FreshTroopChargeArrowRain();
            }
            CheckEnterRetreat();
        }
        else if(m_FlowState == Flow.ShooterAtk)
        {
            if(!allShootFinish)
            {
                allShootFinish = true;
                for (int i = 0; i < m_lisShootingTroops.Count; i++)
                {
                    if (!m_lisShootingTroops[i].AllChildInState(SlgSoldierState.c_sSoldier_Idle))
                    {
                        allShootFinish = false;
                    }
                }
                if (allShootFinish)
                {
                    StepEnterCharge();
                }
            }
            CheckEnterRetreat();
        }
    }

    private Vector3 GetChargeStopPos(bool bLeft)
    {
        Vector3 result = GetTroopHeroPos(bLeft);
        result.x = bLeft ? (result.x - SlgFightDef.FChargeStopGapHero) : (result.x + SlgFightDef.FChargeStopGapHero);
        return result;
    }

    private Vector3 GetTroopHeroPos(bool bLeftTroop)
    {
        foreach (var item in m_DicHeros.Values)
        {
            if(item.m_bLeft == bLeftTroop)
            {
                return item.m_pGameObj.transform.position;
            }
        }
        return Vector3.zero;
    }

    /// <summary>
    /// 获取左右2个方阵  最左边部队的位置  或者最右边部队的位置
    /// </summary>
    /// <param name="bLeftTroop">是左方阵还是右方阵</param>
    /// <param name="leftSide">是最左边还是最右边</param>
    /// <returns></returns>
    private Vector3 GetTroopSidePos(bool bLeftTroop,bool leftSide)
    {
        List<SlgEntityTroop> troops = new List<SlgEntityTroop>();
        foreach (var item in m_DicTroops.Values)
        {
            troops.Add(item);
        }
        return GetTroopSidePos(bLeftTroop, leftSide, troops);

        /*
        Vector3 result = Vector3.zero;
        int pos = 0;
        foreach (var item in m_DicTroops)
        {
            if ((item.Value.m_bLeft && bLeftTroop) ||
                (!item.Value.m_bLeft && !bLeftTroop))
            {
                //这是一个左边的部队
                if(pos == 0)
                {
                    pos = item.Key;
                }
                else
                {
                    if (bLeftTroop)
                    {
                        if (leftSide)
                        {
                            if (SlgFightUtil.ConvertStandPosByPos(item.Key) < SlgFightUtil.ConvertStandPosByPos(pos))
                                pos = item.Key;
                        }
                        else
                        {
                            if (SlgFightUtil.ConvertStandPosByPos(item.Key) > SlgFightUtil.ConvertStandPosByPos(pos))
                                pos = item.Key;
                        }
                    }
                    else
                    {
                        if (leftSide)
                        {
                            if (SlgFightUtil.ConvertStandPosByPos(item.Key) > SlgFightUtil.ConvertStandPosByPos(pos))
                                pos = item.Key;
                        }
                        else
                        {
                            if (SlgFightUtil.ConvertStandPosByPos(item.Key) < SlgFightUtil.ConvertStandPosByPos(pos))
                                pos = item.Key;
                        }
                    }
                }
            }
        }
        if (m_DicTroops.ContainsKey(pos))
            result = m_DicTroops[pos].GetCenter();

        return result;
        */
    }

    private Vector3 GetTroopSidePos(bool bLeftTroop, bool leftSide,List<SlgEntityTroop> troops)
    {
        int pos = 0;
        SlgEntityTroop selectTroop = null;
        for (int i = 0; i < troops.Count; i++)
        {
            SlgEntityTroop item = troops[i];
            if ((item.m_bLeft && bLeftTroop) ||
                (!item.m_bLeft && !bLeftTroop))
            {
                //这是一个左边的部队
                if (pos == 0)
                {
                    pos = item.Pos;
                    selectTroop = item;
                }
                else
                {
                    if (bLeftTroop)
                    {
                        if (leftSide)
                        {
                            if (SlgFightUtil.ConvertStandPosByPos(item.Pos) < SlgFightUtil.ConvertStandPosByPos(pos))
                            {
                                pos = item.Pos;
                                selectTroop = item;
                            }
                        }
                        else
                        {
                            if (SlgFightUtil.ConvertStandPosByPos(item.Pos) > SlgFightUtil.ConvertStandPosByPos(pos))
                            {
                                pos = item.Pos;
                                selectTroop = item;
                            }
                        }
                    }
                    else
                    {
                        if (leftSide)
                        {
                            if (SlgFightUtil.ConvertStandPosByPos(item.Pos) > SlgFightUtil.ConvertStandPosByPos(pos))
                            {
                                pos = item.Pos;
                                selectTroop = item;
                            }
                        }
                        else
                        {
                            if (SlgFightUtil.ConvertStandPosByPos(item.Pos) < SlgFightUtil.ConvertStandPosByPos(pos))
                            {
                                pos = item.Pos;
                                selectTroop = item;
                            }
                        }
                    }
                }
            }
        }
        if (selectTroop != null)
            return selectTroop.GetCenter();
        else
            return Vector3.zero;
    }

    /// <summary>
    /// 获取左右2个方阵的中心点
    /// </summary>
    /// <returns></returns>
    private Vector3 GetSideCenter(bool bLeftTroop)
    {
        Vector3 result = Vector3.zero;
        List<SlgEntityTroop> troops = new List<SlgEntityTroop>();
        foreach (var item in m_DicTroops.Values)
        {
            if(item.m_bLeft == bLeftTroop)
            {
                if (!troops.Contains(item))
                {
                    troops.Add(item);
                }
            }
        }
        result = GetTroopsCenter(troops);
        return result;
    }

    private Vector3 GetTroopsCenter(List<SlgEntityTroop> troops)
    {
        Vector3 result = Vector3.zero;

        for (int i = 0; i < troops.Count; i++)
        {
            result += troops[i].GetCenter();
        }
        if (troops.Count > 0)
            result = result / troops.Count;

        return result;
    }

    /// <summary>
    /// 获取左右2个方阵 部队个数
    /// </summary>
    /// <param name="bLeftTroop"></param>
    /// <returns></returns>
    private int GetSideTroopNum(bool bLeftTroop)
    {
        int result = 0;
        foreach (var item in m_DicTroops)
        {
            if(item.Value.m_bLeft == bLeftTroop)
            {
                result++;
            }
        }
        return result;
    }

    public List<int> GetSideTroopPoss(bool bLeft)
    {
        List<int> results = new List<int>();
        for (int i = 0; i < lis_Soldier.Count; i++)
        {
            if(lis_Soldier[i].m_bleft == bLeft &&
               !results.Contains(lis_Soldier[i].pos))
            {
                results.Add(lis_Soldier[i].pos);
            }
        }
        return results;
    }

    public List<int> GetSideHeroPoss(bool bLeft)
    {
        List<int> result = new List<int>();
        for (int i = 0; i < lis_Hero.Count; i++)
        {
            if(!lis_Hero[i].m_bFilp == bLeft &&
               !result.Contains(lis_Hero[i].index))
            {
                result.Add(lis_Hero[i].index);
            }
        }
        return result;
    }

    private List<SlgEntityTroop> GetArmyTypeTroop(List<int> armyType,bool bLeftTroop)
    {
        List<SlgEntityTroop> result = new List<SlgEntityTroop>();
        foreach (var item in m_DicTroops.Values)
        {
            if(bLeftTroop == item.m_bLeft)
            {
                for (int i = 0; i < armyType.Count; i++)
                {
                    if (item.IsContainsTypeArmy(armyType[i]))
                    {
                        result.Add(item);
                    }
                }
            }
        }

        return result;
    }

    private List<SlgEntityHero> GetSideHero(bool bleft)
    {
        List<SlgEntityHero> heros = new List<SlgEntityHero>();
        foreach (var item in m_DicHeros.Values)
        {
            if(item.m_bLeft == bleft)
            {
                heros.Add(item);
            }
        }
        return heros;
    }

    private Vector3 ConvertTroop2Camera(Vector3 troopPos)
    {
        return new Vector3(troopPos.x, SlgFightDef.FCameraPos.y + m_v3AddCameraPos.y, SlgFightDef.FCameraPos.z + m_v3AddCameraPos.z);
    }

    private List<SlgEntityTroop> GetSortTroop(bool bLeftTroop,bool bLeft2Right)
    {
        List<SlgEntityTroop> lis = new List<SlgEntityTroop>();

        foreach (var item in m_DicTroops.Values)
        {
            if(bLeftTroop == item.m_bLeft)
            {
                lis.Add(item);
            }
        }
        lis.Sort((x, y) =>
        {
            if (bLeftTroop)
            {
            if (SlgFightUtil.ConvertStandPosByPos(x.Pos) < SlgFightUtil.ConvertStandPosByPos(y.Pos))
                {
                    return (bLeft2Right ? -1 : 1);
                }
                else if (SlgFightUtil.ConvertStandPosByPos(x.Pos) == SlgFightUtil.ConvertStandPosByPos(y.Pos))
                {
                    return 0;
                }
                else
                {
                    return (bLeft2Right ? 1 : -1);
                }
            }
            else
            {
                if (SlgFightUtil.ConvertStandPosByPos(x.Pos) > SlgFightUtil.ConvertStandPosByPos(y.Pos))
                {
                    return (bLeft2Right ? -1 : 1);
                }
                else if (SlgFightUtil.ConvertStandPosByPos(x.Pos) == SlgFightUtil.ConvertStandPosByPos(y.Pos))
                {
                    return 0;
                }
                else
                {
                    return (bLeft2Right ? 1 : -1);
                }
            }
        });
        return lis;
    }

    public Transform GetDeadToCamera()
    {
        if (m_pMainCamera.gameObject.activeSelf)
        {
            return m_pMainCamera.transform;
        }
        else
        {
            return null;
        }
    }

    public bool GetNeedFlyToCamera()
    {
        bool result = false;
        Transform tf = GetDeadToCamera();
        result = tf != null && (m_iFlyToCameraNum < SlgFightDef.IDeadToCameraNum);

        if (result)
            m_iFlyToCameraNum++;

        return result;
    }

    private void SetCameraActive(bool bLeft,bool active)
    {
        Transform parent =  bLeft ? m_pLeftCameraParent : m_pRightCameraParent;
        parent.gameObject.SetActive(active);
        if (!active)
        {
            parent.position = new Vector3(0, 1000, 0);
        }
        if(m_pLeftCameraParent.gameObject.activeSelf && m_pRightCameraParent.gameObject.activeSelf)
        {
            SetCameraView(true, m_bLeftCameraInLeft);
        }
        else
        {
            if(m_pRightCameraParent.gameObject.activeSelf ||
                m_pLeftCameraParent.gameObject.activeSelf)
            {
                SetCameraView(false);
            }
        }
    }

    /// <summary>
    /// 设置摄像机的偏移
    /// </summary>
    /// <param name="bSplit">是否启用分屏</param>
    /// <param name="bLeftCameraInLeft">左边摄像机映射在左边</param>
    private void SetCameraView(bool bSplit, bool bLeftCameraInLeft = true)
    {
        HeroBattleLua.C2Lua_ActiveCameraSplitLine(bSplit);
        if (bLeftCameraInLeft)
        {
            m_pLeftCamera.rect = new Rect(0, 0, bSplit ? 0.5f : 1, 1);
            m_pRightCamera.rect = new Rect(bSplit ? 0.5f : 0, 0, bSplit ? 0.5f : 1, 1);
        }
        else
        {
            m_pLeftCamera.rect = new Rect(bSplit ? 0.5f : 0, 0, bSplit ? 0.5f : 1, 1);
            m_pRightCamera.rect = new Rect(0, 0, bSplit ? 0.5f : 1, 1); 
        }
    }

    //2边阅兵
    private void StepEnterReviewTroops(bool bLeft)
    {
        HeroBattleLua.C2Lua_ActiveCameraSplitLine(false);
        m_FlowState = Flow.ReviewTroops;
        if (bLeft)
        {
            //m_pLeftCameraParent.position = ConvertTroop2Camera(GetTroopSidePos(true, true));
            m_pLeftCameraParent.position = ConvertTroop2Camera(GetTroopHeroPos(true));
            foreach (var item in m_DicHeros.Values)
            {
                if (item.m_bLeft == bLeft)
                {
                    item.ChangeState(SlgHeroState.c_sSlgHero_DoBuf);
                }
            }
        }
        else
        {
            //m_pRightCameraParent.position = ConvertTroop2Camera(GetTroopSidePos(false, false));
        }
        SetCameraActive(true, true);
        SetCameraActive(false, false);
        CameraMoveComp cameraMoveComp = m_pLCMoveComp;
        cameraMoveComp.UniformMove(2, ConvertTroop2Camera(GetTroopSidePos(bLeft, false)));

        float moveT = cameraMoveComp.GetRemainingTime();
        int numTroop = GetSideTroopNum(bLeft);
        float t = 0;
        if (numTroop > 1)
            t = moveT / numTroop;

        List<SlgEntityTroop> troops = GetSortTroop(bLeft, true);
        for (int i = 0; i < numTroop; i++)
        {
            int index = i;
            if (i < troops.Count)
            {
                AddTimer(() =>
                {
                    DoTroopBuf(troops[index].Pos);
                    List<SlgEntitySoldier> soldiers = troops[index].GetAllSoldier();
                    for (int j = 0; j < soldiers.Count; j++)
                    {
                        soldiers[j].ChangeState(SlgSoldierState.c_sSolider_Action,SlgFightDef.c_sAction_Skill);
                    }
                }, t * i,"播放动作结束");
            }
        }

        if (bLeft)
        {
            //移动到左边部队的最右边
            cameraMoveComp.RegOnArrive(() =>
            {
                cameraMoveComp.ClearOnArrive();
                AddTimer(() => 
                {
                    cameraMoveComp.UniformMove(80, ConvertTroop2Camera(GetTroopSidePos(false, true)));
                    //移动到 右边不对的 最左边
                    cameraMoveComp.RegOnArrive(() =>
                    {
                        cameraMoveComp.ClearOnArrive();
                        StepEnterReviewTroops(false);
                    });

                }, 1);
            });
        }
        else
        {
            Debug.Log("Star Over");
            cameraMoveComp.RegOnArrive(() => 
            {
                cameraMoveComp.ClearOnArrive();
                AddTimer(() => 
                {
                    Debug.Log("End Over");
                    StepCenterUIAni();

                }, 1);
            });
        }
    }
    private void StepEnterReviewTroops2(bool bLeft)
    {
        HeroBattleLua.C2Lua_ActiveCameraSplitLine(false);
        m_FlowState = Flow.ReviewTroops;
        SetCameraActive(true, true);
        SetCameraActive(false, false);
        CameraMoveComp cameraMoveComp = m_pLCMoveComp;
        if (bLeft)
        {
            Vector3 heroPos = GetTroopHeroPos(true);
            m_pLeftCameraParent.position = ConvertTroop2Camera(new Vector3(heroPos.x + (bLeft ? SlgFightDef.FStartBetweenHero : -SlgFightDef.FStartBetweenHero),
                                                                           heroPos.y, heroPos.z));
            foreach (var item in m_DicHeros.Values)
            {
                if (item.m_bLeft == bLeft)
                {
                    item.ChangeState(SlgHeroState.c_sSlgHero_DoBuf);
                }
            }
            cameraMoveComp.UniformMove(SlgFightDef.FCameraMoveSpeed01, ConvertTroop2Camera(GetTroopSidePos(true, true)));
            cameraMoveComp.RegOnArrive(() =>
            {
                //到达   左边部队的最左边
                cameraMoveComp.ClearOnArrive();
                cameraMoveComp.UniformMove(SlgFightDef.FCameraMoveSpeed01, ConvertTroop2Camera(GetTroopSidePos(true, false)));
                //TroopDoBuf(bLeft, cameraMoveComp);
                TroopDoWave(bLeft, cameraMoveComp);

                cameraMoveComp.RegOnArrive(() => 
                {
                    //到达   左边部队的最右边
                    cameraMoveComp.ClearOnArrive();
                    cameraMoveComp.StopMove();
                    AddTimer(() =>
                    {
                        HeroBattleLua.C2Lua_FreshScreen(SlgFightDef.FFreshScreenDuration);
                        AddTimer(() =>
                        {
                            StepEnterReviewTroops2(false);
                        }, SlgFightDef.FFreshScreenDuration);

                        AddTimer(() =>
                        {
                            m_pLeftCameraParent.position = ConvertTroop2Camera(GetTroopSidePos(false, true));
                        }, SlgFightDef.FFreshScreenDelayMoveCamera);

                    }, SlgFightDef.FCameraWaitLeft);
                    //AddTimer(() => 
                    //{
                    //    cameraMoveComp.UniformMove(SlgFightDef.FCameraMoveSpeed02, ConvertTroop2Camera(GetTroopSidePos(false, true)));
                    //    cameraMoveComp.RegOnArrive(() =>
                    //    {
                    //        //到达  右边部队的最左边
                    //        cameraMoveComp.ClearOnArrive();

                    //        AddTimer(() =>
                    //        {
                    //            StepEnterReviewTroops2(false);
                    //        }, SlgFightDef.FLeft2RightRest);
                    //    });
                    //}, 1);
                });
            });
        }
        else
        {
            cameraMoveComp.UniformMove(SlgFightDef.FCameraMoveSpeed01, ConvertTroop2Camera(GetTroopSidePos(false, false)));
            //TroopDoBuf(bLeft, cameraMoveComp);
            TroopDoWave(bLeft, cameraMoveComp);
            cameraMoveComp.RegOnArrive(() => 
            {
                //到达    右边部队的最右边
                cameraMoveComp.ClearOnArrive();
                Vector3 heroPos = GetTroopHeroPos(false);

                cameraMoveComp.UniformMove(SlgFightDef.FCameraMoveSpeed01, ConvertTroop2Camera(new Vector3(heroPos.x + (bLeft ? SlgFightDef.FStartBetweenHero : -SlgFightDef.FStartBetweenHero),
                                                                           heroPos.y, heroPos.z)));
                cameraMoveComp.RegOnArrive(() => 
                {
                    //到达    右边部队的英雄位置
                    cameraMoveComp.ClearOnArrive();
                    foreach (var item in m_DicHeros.Values)
                    {
                        if (item.m_bLeft == bLeft)
                        {
                            item.ChangeState(SlgHeroState.c_sSlgHero_DoBuf);
                        }
                    }

                    //过1秒镜头移动到中间
                    AddTimer(() =>
                    {
                        Debug.Log("End Over");
                        StepCenterUIAni();

                    }, 3);
                });

            });
        }

        //float moveT = cameraMoveComp.GetRemainingTime();
        //int numTroop = GetSideTroopNum(bLeft);
        //float t = 0;
        //if (numTroop > 1)
        //    t = moveT / numTroop;

        //List<SlgEntityTroop> troops = GetSortTroop(bLeft, true);
        //for (int i = 0; i < numTroop; i++)
        //{
        //    int index = i;
        //    if (i < troops.Count)
        //    {
        //        AddTimer(() =>
        //        {
        //            DoTroopBuf(troops[index].Pos);
        //            List<SlgEntitySoldier> soldiers = troops[index].GetAllSoldier();
        //            for (int j = 0; j < soldiers.Count; j++)
        //            {
        //                soldiers[j].ChangeState(SlgSoldierState.c_sSolider_Action, SlgFightDef.c_sAction_Skill);
        //            }
        //        }, t * i, "播放动作结束");
        //    }
        //}

        //if (bLeft)
        //{
        //    //移动到左边部队的最右边
        //    cameraMoveComp.RegOnArrive(() =>
        //    {
        //        cameraMoveComp.ClearOnArrive();
        //        AddTimer(() =>
        //        {
        //            cameraMoveComp.UniformMove(80, ConvertTroop2Camera(GetTroopSidePos(false, true)));
        //            //移动到 右边不对的 最左边
        //            cameraMoveComp.RegOnArrive(() =>
        //            {
        //                cameraMoveComp.ClearOnArrive();
        //                StepEnterReviewTroops(false);
        //            });

        //        }, 1);
        //    });
        //}
        //else
        //{
        //    Debug.Log("Star Over");
        //    cameraMoveComp.RegOnArrive(() =>
        //    {
        //        cameraMoveComp.ClearOnArrive();
        //        AddTimer(() =>
        //        {
        //            Debug.Log("End Over");
        //            StepCenterUIAni();

        //        }, 1);
        //    });
        //}
    }
    private void TroopDoBuf(bool bLeft,CameraMoveComp cameraMoveComp)
    {
        //部队做动作
        float moveT = cameraMoveComp.GetRemainingTime();
        int numTroop = GetSideTroopNum(bLeft); 
        float t = 0;
        if (numTroop > 1)
            t = moveT / (numTroop-1);

        Debug.LogFormat("进入时间:{0}  移动需要时间:{1}  移动到下一组需要的时间:{2}  部队个数:{3}", Time.time, moveT, t, numTroop);
        List<SlgEntityTroop> troops = GetSortTroop(bLeft, true);
        for (int i = 0; i < numTroop; i++)
        {
            int index = i;
            if (i < troops.Count)
            {
                AddTimer(() =>
                {
                    Debug.LogFormat("当前的时间：{0}  {1}", Time.time, index);
                    DoTroopBuf(troops[index].Pos);
                    List<SlgEntitySoldier> soldiers = troops[index].GetAllSoldier();
                    for (int j = 0; j < soldiers.Count; j++)
                    {
                        soldiers[j].ChangeState(SlgSoldierState.c_sSolider_Action, SlgFightDef.c_sAction_Skill);
                    }
                }, t * i, "播放动作结束");
            }
        }
    }
    private void TroopDoWave(bool bLeft, CameraMoveComp cameraMoveComp)
    {
        //部队做动作
        float moveT = cameraMoveComp.GetRemainingTime();
        int numTroop = GetSideTroopNum(bLeft);
        float t = 0;
        if (numTroop > 1)
            t = moveT / (numTroop - 1);
        
        List<SlgEntityTroop> troops = GetSortTroop(bLeft, true);
        for (int i = 0; i < numTroop; i++)
        {
            int index = i;
            if (i < troops.Count)
            {
                AddTimer(() =>
                {
                    List<SlgEntitySoldier> soldiers = troops[index].GetAllSoldier();
                    if (troops[index].m_bLeft)
                    {
                        for (int j = 0; j < soldiers.Count; j++)
                        {
                            int index2 = j;
                            SlgEntitySoldier solider = troops[index].GetSoldierByIndex(index2);
                            if (solider != null && !solider.m_bDead)
                            {
                                AddTimer(() =>
                                {
                                    solider.ChangeState(SlgSoldierState.c_sSolider_Action, SlgFightDef.c_sAction_Skill);
                                }, 0.1f * index2);
                            }
                        }
                    }
                    else
                    {
                        //哎.. 现在想要海浪的阅兵 那么站位只能是 方格的数组,之前的站位编辑器方案就不行了这边写死了.. 5*8站位了
                        int heng = 5;
                        int shu = 8;
                        int waitTime = 0;
                        for (int m = heng-1; m >= 0; m--)
                        {
                            for (int n = 0; n < shu; n++)
                            {
                                int index3 = m * shu + n;
                                SlgEntitySoldier solider = troops[index].GetSoldierByIndex(index3);
                                if (solider != null && !solider.m_bDead)
                                {
                                    AddTimer(() =>
                                    {
                                        solider.ChangeState(SlgSoldierState.c_sSolider_Action, SlgFightDef.c_sAction_Skill);
                                    }, 0.1f * waitTime);
                                    waitTime++;
                                }
                            }
                        }
                    }
                    


                    //for (int j = 0; j < soldiers.Count; j++)
                    //{
                    //    soldiers[j].ChangeState(SlgSoldierState.c_sSolider_Action, SlgFightDef.c_sAction_Skill);
                    //}
                }, t * i - (0.5f*t), "播放动作结束");
            }
        }
    }

    //镜头移到中间 英雄开始放Buf
    private void StepEnterDoBufSkill(bool bleft)
    {
        bufIndex = -1;
        m_FlowState = Flow.DoBufSkill;
        CameraMoveComp cameraMoveComp = bleft ? m_pLCMoveComp : m_pRCMoveComp;
        if( (bleft && lis_LeftDoBuff.Count > 0) ||
            (!bleft && lis_RightDoBuff.Count > 0))
        {
            cameraMoveComp.UniformMove(10, ConvertTroop2Camera(GetSideCenter(bleft)));
            cameraMoveComp.RegOnArrive(() =>
            {
                cameraMoveComp.ClearOnArrive();
                //放Buf技能
                DoHeroBuf(bleft);
            });
        }
        else
        {
            DoHeroBuf(bleft);
        }
    }
    private void DoHeroBuf(bool bleft)
    {
        DoBuff buf = null;
        bufIndex++;
        if (bleft)
        {
            if(bufIndex >= lis_LeftDoBuff.Count)
            {
                //左边结束 -> 切到右边
                StepEnterReviewTroops(false);
                return;
            }
            else
            {
                buf = lis_LeftDoBuff[bufIndex];
            }
        }
        else
        {
            if(bufIndex >= lis_RightDoBuff.Count)
            {
                //右边结束 -> UI动画
                StepCenterUIAni();
                return;
            }
            else
            {
                buf = lis_RightDoBuff[bufIndex];
            }
        }
        if(buf != null)
        {
            AddTimer(() =>
            {
                DoHeroBuf(bleft);
            }, 3, "英雄放BUF技能");

            //播技能特效
            if (m_DicHeros.ContainsKey(buf.doPos))
            {
                m_DicHeros[buf.doPos].ChangeState(SlgHeroState.c_sSlgHero_DoBuf);
            }
            foreach (var item in buf.bufs.Values)
            {
                if (m_DicTroops.ContainsKey(item.defPos))
                {
                    SlgEntityTroop defTroop = m_DicTroops[item.defPos];
                    for (int j = 0; j < item.bufIds.Count; j++)
                    {
                        SkillEffect skillEff = ConfigManager.Instance.SkillEffectLoader.GetInfoById(item.bufIds[j]);
                        BattleEffectMgr.Instance.CreateEffectObj(8001, defTroop.GetCenter());
                    }
                }
                else
                {
                    Debug.LogFormat("buf的作用对象没找到");
                }
            }
        }
    }

    /// <summary>
    /// 产生这个单位 所有的BUF特效
    /// </summary>
    private void DoTroopBuf(int troopIndex)
    {
        if (!m_DicTroops.ContainsKey(troopIndex))
        {
            return;
        }

        List<int> bufIds = new List<int>();
        for (int i = 0; i < lis_DoBuff.Count; i++)
        {
            foreach (var item in lis_DoBuff[i].bufs.Values)
            {
                for (int j = 0; j < item.bufIds.Count; j++)
                {
                    if(troopIndex == item.defPos)
                    {
                        if (!bufIds.Contains(item.bufIds[j]))
                        {
                            bufIds.Add(item.bufIds[j]);
                        }
                    }
                }
            }
        }

        SlgEntityTroop defTroop = m_DicTroops[troopIndex];
        List<int> effIds = new List<int>();
        for (int j = 0; j < bufIds.Count; j++)
        {
            SkillEffect skillEff = ConfigManager.Instance.SkillEffectLoader.GetInfoById(bufIds[j]);
            if (!effIds.Contains(skillEff.heroBatEffectId))
            {
                effIds.Add(skillEff.heroBatEffectId);
                if (skillEff.heroBatEffType == SlgFightDef.c_iHeroEffType_Trooo)
                {
                    BattleEffectMgr.Instance.CreateEffectObj(skillEff.heroBatEffectId, defTroop.GetCenter());
                }
                else if (skillEff.heroBatEffType == SlgFightDef.c_iHeroEffType_Unit)
                {
                    List<SlgEntitySoldier> soldiers = defTroop.GetAliveSoldier();
                    for (int i = 0; i < soldiers.Count; i++)
                    {
                        BattleEffectMgr.Instance.CreateEffectObj(skillEff.heroBatEffectId, soldiers[i].m_pGameObj.transform.position);
                    }
                }
            }
        }
    }

    private void StepCenterUIAni()
    {
        m_FlowState = Flow.CenterUIAnimation;
        m_pLCMoveComp.StopMove();
        List<SlgEntityTroop> leftShooters = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow, SlgFightDef.c_iArmyType_Tank }, true);
        List<SlgEntityTroop> rightShooters = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow, SlgFightDef.c_iArmyType_Tank }, false);
        List<SlgEntityTroop> leftBattle = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight}, true);
        List<SlgEntityTroop> rightBattle = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, false);
        if(leftShooters.Count > 0)
        {
            m_pLeftCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(leftShooters));
        }
        else
        {
            if(leftBattle.Count > 0)
            {
                m_pLeftCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(leftBattle));
            }
        }
        if (leftShooters.Count > 0)
        {
            m_pRightCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(rightShooters));
        }
        else
        {
            if (leftBattle.Count > 0)
            {
                m_pRightCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(rightBattle));
            }
        }

        SetCameraActive(true, true);
        SetCameraActive(false, true);
        HeroBattleLua.C2Lua_StartUIAni();

        //m_pLCMoveComp.UniformMove(SlgFightDef.FCameraMoveSpeed03, ConvertTroop2Camera(Vector3.zero));
        //m_pLCMoveComp.RegOnArrive(() =>
        //{
        //    m_pLCMoveComp.ClearOnArrive();
        //    HeroBattleLua.C2Lua_StartUIAni();
        //});

        //m_pRCMoveComp.UniformMove(50, ConvertTroop2Camera(Vector3.zero));
        //m_pRCMoveComp.RegOnArrive(()=> 
        //{
        //    m_pRCMoveComp.ClearOnArrive();
        //    HeroBattleLua.C2Lua_StartUIAni();
        //});
    }
    public void StepCenterUIAniEnd()
    {
        AddTimer(() => 
        {
            StepEnterShooterAtk();
        }, SlgFightDef.FUIDuration);


        //SetCameraView(true);
        //m_pLCMoveComp.StopMove();
        //m_pRCMoveComp.StopMove();
        //m_pLeftCameraParent.gameObject.SetActive(true);
        //m_pRightCameraParent.gameObject.SetActive(true);
        //m_pLeftCameraParent.position = ConvertTroop2Camera(GetTroopSidePos(true, true));
        //m_pRightCameraParent.position = ConvertTroop2Camera(GetTroopSidePos(false, false));
    }
    private void StepEnterShooterAtk()
    {
        m_FlowState = Flow.ShooterAtk;
        allShootFinish = true;
        m_pLCMoveComp.StopMove();
        m_pRCMoveComp.StopMove();
        //m_pLeftCameraParent.gameObject.SetActive(false);
        //m_pRightCameraParent.gameObject.SetActive(false);
        //SetCameraActive(true, false);
        //SetCameraActive(false, false);
        List<SlgEntityTroop> leftShooters = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow, SlgFightDef.c_iArmyType_Tank }, true);
        List<SlgEntityTroop> rightShooters = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow, SlgFightDef.c_iArmyType_Tank }, false);

        SetCameraActive(true, false);
        SetCameraActive(false, false);
        if (leftShooters.Count >0 && rightShooters.Count > 0)
        {
            //2边都有射手
            TroopShoot(true,leftShooters);
            TroopShoot(false,rightShooters);
        }
        else
        {
            if(leftShooters.Count <= 0 && rightShooters.Count <= 0)
            {
                //2边都没有射手
                StepEnterCharge();
            }
            else
            {
                if (leftShooters.Count > 0)
                {
                    //只有左边有射手
                    TroopShoot(true,leftShooters);
                    //SetCameraViewOnlyOneSide(true);
                }
                else
                {
                    //只有右边有射手
                    TroopShoot(false,rightShooters);
                    //SetCameraViewOnlyOneSide(false);
                }
            }
        }
    }
    private void TroopShoot(bool bLeft,List<SlgEntityTroop> shooters)
    {
        m_lisShootingTroops.AddRange(shooters);
        Transform cameraParent = bLeft ? m_pLeftCameraParent : m_pRightCameraParent;
        SetCameraActive(bLeft, true);
        Vector3 center = GetTroopsCenter(shooters);
        cameraParent.position = ConvertTroop2Camera(center);

        for (int i = 0; i < shooters.Count; i++)
        {
            SlgEntityTroop troop = shooters[i];
            List<SlgEntitySoldier> soldiers = troop.GetAliveSoldier();
            for (int j = 0; j < soldiers.Count; j++)
            {
                int index = j;
                AddTimer(() => 
                {
                    allShootFinish = false;
                    soldiers[index].ChangeState(SlgSoldierState.c_sSolider_Shoot);
                }, UnityEngine.Random.Range(0f, 0.5f));
            }
        }
    }
    public void StepEnterCharge()
    {
        if (m_FlowState == Flow.Charge)
            return;

        m_FlowState = Flow.Charge;
        
        List<SlgEntityTroop> leftShooters = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow, SlgFightDef.c_iArmyType_Tank }, true);
        List<SlgEntityTroop> rightShooters = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow, SlgFightDef.c_iArmyType_Tank }, false);
        List<SlgEntityTroop> leftWarrior = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, true);
        List<SlgEntityTroop> rightWarrior = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, false);
        SetCameraActive(true, false);
        SetCameraActive(false, false);

        bool noShooter = (leftShooters.Count <= 0 && rightShooters.Count <= 0);
        bool noWarrior = (leftWarrior.Count <= 0 && rightWarrior.Count <= 0);
        if (noShooter)
        {
            if (noWarrior)
            {
                //StepEnterOver();
                //不怎么可能2个都没...
                StepEnterRetreat();
            }
            else
            {
                //有士兵没射箭
                TroopCharge(true, leftWarrior);
                TroopCharge(false, rightShooters);
            }
        }
        else
        {
            //有射箭那么就有剑雨

            //没有士兵  远程互射
            if (noWarrior)
            {
                if (leftShooters.Count > 0)
                {
                    TroopArrowRain(true, leftShooters);
                }
                   
                if (rightShooters.Count > 0)
                {
                    TroopArrowRain(false, rightShooters);
                }
            }
            else
            {
                //有士兵
                float t = 0;
                if (leftShooters.Count > 0)
                {
                    m_pLeftCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(leftShooters));
                    SetCameraActive(true, true);
                }
                if (rightShooters.Count > 0)
                {
                    m_pRightCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(rightShooters));
                    SetCameraActive(false, true);
                }

                if (leftWarrior.Count > 0 && rightShooters.Count > 0)
                {
                    Vector3 pos = GetTroopsCenter(leftWarrior);
                    pos = ConvertTroop2Camera(pos);
                    m_pLCMoveComp.UniformMove(SlgFightDef.FCameraShoot2BattleMan, pos);
                    t = m_pLCMoveComp.GetRemainingTime();


                    t = t - SlgFightDef.FBattleManAhearMoveTime;
                    if (t < 0)
                        t = 0;

                    AddTimer(() =>
                    {
                        AddTroopChargeArrowRain(false, leftWarrior);
                    }, SlgFightDef.FDelayArrow + t);
                }
                AddTimer(() => 
                {
                    TroopCharge(true, leftWarrior,false);
                }, t);
                AddTimer(() =>
                {
                    m_lisLeftChargeTroops = leftWarrior;
                    m_fLeftUpPass = 0;
                    m_fLeftDownPass = 0;
                }, t + SlgFightDef.FBattleManAhearMoveTime);

                Debug.Log("移动所需时间T： " + t);
                t = 0;
                if (rightWarrior.Count > 0 && leftShooters.Count > 0)
                {
                    Vector3 pos = GetTroopsCenter(rightWarrior);
                    pos = ConvertTroop2Camera(pos);
                    m_pRCMoveComp.UniformMove(SlgFightDef.FCameraShoot2BattleMan, pos);
                    t = m_pRCMoveComp.GetRemainingTime();
                    t = t - SlgFightDef.FBattleManAhearMoveTime;
                    if (t < 0)
                        t = 0;

                    AddTimer(() =>
                    {
                        AddTroopChargeArrowRain(true, rightWarrior);
                    }, SlgFightDef.FDelayArrow + t);
                }
                AddTimer(() =>
                {
                    TroopCharge(false, rightWarrior,false);
                }, t);
                AddTimer(() => 
                {
                    m_lisRightChargeTroops = rightWarrior;
                    m_fRightUpPass = 0;
                },t+SlgFightDef.FBattleManAhearMoveTime);
                Debug.Log("移动所需时间T： " + t);
            }
        }
    }

    /// <summary>
    /// 冲刺
    /// </summary>
    /// <param name="bLeft"></param>
    /// <param name="warriors"></param>
    private void TroopCharge(bool bLeft,List<SlgEntityTroop> warriors,bool cameraFlow = true)
    {
        Transform cameraParent = bLeft ? m_pLeftCameraParent : m_pRightCameraParent;
        SetCameraActive(bLeft, warriors.Count > 0);
        if (warriors.Count <= 0)
        {
            return;
        }
        m_bCharge = true;
        if (!cameraParent.gameObject.activeSelf)
        {
            Vector3 center = GetTroopsCenter(warriors);
            cameraParent.position = ConvertTroop2Camera(center);
        }
        if (cameraFlow)
        {
            if (bLeft)
            {
                m_lisLeftChargeTroops = warriors;
                m_fLeftUpPass = 0;
                m_fLeftDownPass = 0;
            }
            else
            {
                m_lisRightChargeTroops = warriors;
                m_fRightUpPass = 0;
            }
        }
        for (int i = 0; i < warriors.Count; i++)
        {
            SlgEntityTroop troop = warriors[i];
            List<SlgEntitySoldier> soldiers = troop.GetAliveSoldier();
            for (int j = 0; j < soldiers.Count; j++)
            {
                soldiers[j].ChangeState(SlgSoldierState.c_sSoldier_Move, soldiers[j].GetForwardDir());
            }
        }
    }
    /// <summary>
    /// 冲刺之后回来
    /// </summary>
    private void CheckChargeBack()
    {

    }
    /// <summary>
    /// 下箭雨 - 自行检测下在哪个部队前方
    /// </summary>
    /// <param name="bLeft">目标左边,右边</param>
    private void TroopArrowRain(bool bLeft,List<SlgEntityTroop> defTroops)
    {
        Transform cameraParent = bLeft ? m_pLeftCameraParent : m_pRightCameraParent;
        SetCameraActive(bLeft, defTroops.Count > 0);
        if (defTroops.Count <= 0)
        {
            return;
        }
        Vector3 center = GetTroopsCenter(defTroops);
        cameraParent.position = ConvertTroop2Camera(center);

        DoArrowRain(bLeft, center);

        AddTimer(() => 
        {
            List<SlgEntityTroop> atkTroops = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow, SlgFightDef.c_iArmyType_Tank }, !bLeft);
            for (int i = 0; i < atkTroops.Count; i++)
            {
                SlgEntityTroop atk = atkTroops[i];
                for (int j = 0; j < defTroops.Count; j++)
                {
                    SlgEntityTroop def = defTroops[j];
                    if (m_DicDmg.ContainsKey(atk.Pos))
                    {
                        for (int k = 0; k < m_DicDmg[atk.Pos].Count; k++)
                        {
                            if (!m_DicDmg[atk.Pos][k].done && m_DicDmg[atk.Pos][k].defTroopId == def.Pos)
                            {
                                m_DicDmg[atk.Pos][k].done = true;
                                def.RandomDeadByDmg(m_DicDmg[atk.Pos][k].dmg);
                            }
                        }
                    }

                }
            }

        }, SlgFightDef.FFirstArrowShootDelayDmg);
    }

    private void DoArrowRain(bool bLeft,Vector3 center)
    {
        List<SlgEntityTroop> atkShoot = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow }, !bLeft);
        bool bAtkShoot = atkShoot.Count > 0;
        for (int i = 0; i < atkShoot.Count; i++)
        {
            if (atkShoot[i].IsAllDead())
            {
                bAtkShoot = false;
            }
        }

        List<SlgEntityTroop> atkTank = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Tank }, !bLeft);
        bool bAtkTank = atkTank.Count > 0;
        for (int i = 0; i < atkTank.Count; i++)
        {
            if (atkTank[i].IsAllDead())
            {
                bAtkTank = false;
            }
        }

        int rMin = 0;
        int rMax = 100;
        if(bAtkShoot && !bAtkTank)
        {
            rMin = 0;
            rMax = 70;
        }
        if(!bAtkShoot && bAtkTank)
        {
            rMin = 70;
            rMax = 100;
        }


        for (int i = 0; i < SlgFightDef.IArrowShootDownNum; i++)
        {
            int bulletId = UnityEngine.Random.Range(rMin, rMax);
            bulletId = (bulletId <= 70) ? 9001 : 11003;
            Vector3 start = Vector3.zero;
            Vector3 end = Vector3.zero;
            SlgFightUtil.GetShootStart(bLeft, center, 3, 2, ref start, ref end);
            SlgEntityBullet bulletEntity = BattleEntityFactory.Instance.CreateBtEntity<SlgEntityBullet>();
            bulletEntity.OnCreate(FlyItemStateType.Line,
                          bulletId,
                          start,
                          end,
                          10,
                          false);
            if(bulletId == 11003)
            {
                bulletEntity.RegOnArrive(() =>
                {
                    BattleEffectMgr.Instance.CreateEffectObj(11004, bulletEntity.m_pGameObj.transform.position);
                    if (m_pLeftCameraParent.gameObject.activeSelf)
                    {
                        DKLuaUtil.ShakeTransform(m_pLeftCamera.transform, SlgBattleProperty.Instance.m_fShakeCamera_Duration,
                        SlgBattleProperty.Instance.m_fShakeCamera_Range,
                        SlgBattleProperty.Instance.m_fShakeCamera_Vib,
                        SlgBattleProperty.Instance.m_fShakeCamera_Randomness);

                        AddTimer(() => 
                        {
                            m_pLeftCamera.transform.localPosition = Vector3.zero;
                        }, SlgBattleProperty.Instance.m_fShakeCamera_Duration);
                    }

                    if (m_pRightCameraParent.gameObject.activeSelf)
                    {
                        DKLuaUtil.ShakeTransform(m_pRightCamera.transform, SlgBattleProperty.Instance.m_fShakeCamera_Duration,
                        SlgBattleProperty.Instance.m_fShakeCamera_Range,
                        SlgBattleProperty.Instance.m_fShakeCamera_Vib,
                        SlgBattleProperty.Instance.m_fShakeCamera_Randomness);

                        AddTimer(() => 
                        {
                            m_pRightCamera.transform.localPosition = Vector3.zero;
                        }, SlgBattleProperty.Instance.m_fShakeCamera_Duration);
                    }
                });
            }
        }
    }

    private void AddTroopChargeArrowRain(bool bLeft, List<SlgEntityTroop> defTroops)
    {
        for (int i = 0; i < defTroops.Count; i++)
        {
            if (!m_lisDefShootTroops.Contains(defTroops[i]))
            {
                m_lisDefShootTroops.Add(defTroops[i]);
                m_fNextArrowRainTime = PassTime;

                List<SlgEntityTroop> atkTroops = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow, SlgFightDef.c_iArmyType_Tank }, bLeft);
                for (int i2 = 0; i2 < atkTroops.Count; i2++)
                {
                    SlgEntityTroop atk = atkTroops[i2];
                    for (int j = 0; j < defTroops.Count; j++)
                    {
                        SlgEntityTroop def = defTroops[j];
                        if (m_DicDmg.ContainsKey(atk.Pos))
                        {
                            for (int k = 0; k < m_DicDmg[atk.Pos].Count; k++)
                            {
                                if (!m_DicDmg[atk.Pos][k].done && m_DicDmg[atk.Pos][k].defTroopId == def.Pos)
                                {
                                    m_DicDmg[atk.Pos][k].done = true;
                                    def.AddNeedDeadNum(m_DicDmg[atk.Pos][k].dmg);
                                }
                            }
                        }

                    }
                }
            }
        }
    }
    /// <summary>
    /// 骑兵持续 下箭雨 
    /// </summary>
    private void FreshTroopChargeArrowRain()
    {
        if(m_fNextArrowRainTime <= PassTime)
        {
            m_fNextArrowRainTime = PassTime + SlgFightDef.FArrowRainGap;
            for (int i = 0; i < m_lisDefShootTroops.Count; i++)
            {
                int index = i;
                bool runOverMiddle = false;
                if (m_lisDefShootTroops[i].m_bLeft)
                {
                    runOverMiddle = m_lisDefShootTroops[i].GetCenter().x > 3;
                }
                else
                {
                    runOverMiddle = m_lisDefShootTroops[i].GetCenter().x < -3;
                }
                if (runOverMiddle)
                    break;

                DoArrowRain(m_lisDefShootTroops[i].m_bLeft, m_lisDefShootTroops[i].GetCenter());
                
                AddTimer(() => 
                {
                    int max = 5;
                    if (max > m_lisDefShootTroops[index].INeedDeadNum)
                        max = m_lisDefShootTroops[index].INeedDeadNum;

                    //Debug.LogFormat("si :{0}  {1} ", index,max);
                    max = UnityEngine.Random.Range(1, max);
                    m_lisDefShootTroops[index].INeedDeadNum -= max;
                    m_lisDefShootTroops[index].RandomDeadByNum(max, true);

                }, SlgFightDef.FFirstArrowShootDelayDmg);
            }
        }
    }

    private void SetTroopMaxMoveSpeed(bool bLeft,List<int> troopType,float speed)
    {
        List<SlgEntityTroop> chargeTroops = GetArmyTypeTroop(troopType, bLeft);
        for (int i = 0; i < chargeTroops.Count; i++)
        {
            chargeTroops[i].SetMaxSpeed(speed);
        }
    }

    /// <summary>
    /// 检查小兵的死亡
    /// </summary>
    private void CheckTroopImpact()
    {
        SlgEntityTroop attack = null;
        SlgEntityTroop def = null;
        float dis = 1;
        for (int i = 0; i < m_lisTroops.Count; i++)
        {
            attack = m_lisTroops[i];
            for (int j = 0; j < m_lisTroops.Count; j++)
            {
                def = m_lisTroops[j];
                if (attack.m_bLeft != def.m_bLeft)
                {
                    if (m_DicDmg.ContainsKey(attack.Pos))
                    {
                        for (int k = 0; k < m_DicDmg[attack.Pos].Count; k++)
                        {
                            if (!m_DicDmg[attack.Pos][k].done && m_DicDmg[attack.Pos][k].defTroopId == def.Pos)
                            {
                                if (Vector3.Distance(attack.GetCenter(), def.GetCenter()) <= (dis+SlgFightDef.FDmgOffSet))
                                {
                                    m_DicDmg[attack.Pos][k].done = true;
                                    def.RandomDeadByDmg(m_DicDmg[attack.Pos][k].dmg,true);
                                    if (def.m_bLeft)
                                    {
                                        DKLuaUtil.ShakeTransform(m_pRightCamera.transform, SlgBattleProperty.Instance.m_fShakeCamera_Duration,
                                           SlgBattleProperty.Instance.m_fShakeCamera_Range,
                                           SlgBattleProperty.Instance.m_fShakeCamera_Vib,
                                           SlgBattleProperty.Instance.m_fShakeCamera_Randomness);
                                        AddTimer(() => 
                                        {
                                            m_pRightCamera.transform.localPosition = Vector3.zero;
                                        }, SlgBattleProperty.Instance.m_fShakeCamera_Duration);
                                    }
                                    else
                                    {
                                        DKLuaUtil.ShakeTransform(m_pLeftCamera.transform, SlgBattleProperty.Instance.m_fShakeCamera_Duration,
                                            SlgBattleProperty.Instance.m_fShakeCamera_Range,
                                            SlgBattleProperty.Instance.m_fShakeCamera_Vib,
                                            SlgBattleProperty.Instance.m_fShakeCamera_Randomness);
                                        AddTimer(() =>
                                        {
                                            m_pLeftCamera.transform.localPosition = Vector3.zero;
                                        }, SlgBattleProperty.Instance.m_fShakeCamera_Duration);
                                    }
                                        
                                    if (m_pMainCamera.gameObject.activeSelf)
                                    {
                                        DKLuaUtil.ShakeTransform(m_pMainCamera.transform, SlgBattleProperty.Instance.m_fShakeCamera_Duration,
                                            SlgBattleProperty.Instance.m_fShakeCamera_Range,
                                            SlgBattleProperty.Instance.m_fShakeCamera_Vib,
                                            SlgBattleProperty.Instance.m_fShakeCamera_Randomness);

                                        m_fSpeed = SlgBattleProperty.Instance.m_fShakeTimeScale;
                                        AddTimer(() => 
                                        {
                                            m_fSpeed = 1;
                                        }, SlgBattleProperty.Instance.m_fShakeTimeScaleRecover);
                                    }

                                    //m_fSpeed = 0.15f;
                                    //AddTimer(() =>
                                    //{
                                    //    m_fSpeed = 1f;
                                    //}, 0.3f);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    /// <summary>
    /// 检查摄像机融合 与 分开
    /// </summary>
    private void CheckCameraFuse()
    {
        //检测合并
        if (!m_pMainCamera.gameObject.activeSelf && !m_bFused)
        {
            if (Vector3.Distance(m_pLeftCamera.transform.position, m_pRightCamera.transform.position) < (m_fCameraDis))
            {
                m_bFused = true;
                SetCameraView(false);
                m_pMainCamera.transform.gameObject.SetActive(true);
                m_pMainCamera.transform.position = m_pLeftCamera.transform.position +
                Vector3.Normalize(m_pRightCamera.transform.position - m_pLeftCamera.transform.position) *
                Vector3.Distance(m_pLeftCamera.transform.position, m_pRightCamera.transform.position) / 2;
                m_pLeftCamera.gameObject.SetActive(false);
                m_pRightCamera.gameObject.SetActive(false);
                SetTroopMaxMoveSpeed(true, new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, SlgFightDef.FCrashSpeedMax);
                SetTroopMaxMoveSpeed(false, new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, SlgFightDef.FCrashSpeedMax);
                //HeroBattleLua.C2Lua_FreshScreen(SlgBattleProperty.Instance.m_fCameraFuseFreshDurtion);
            }
        }
        //合并之后  检测分开
        if (m_bFused && m_bFuse2Split)
        {
            if (Vector3.Distance(m_pLeftCamera.transform.position, m_pRightCamera.transform.position) > (m_fCameraDis+1))
            {
                m_bFuse2Split = false;

                AddTimer(() =>
                {
                    //HeroBattleLua.C2Lua_FreshScreen(SlgBattleProperty.Instance.m_fCameraFuseFreshDurtion);
                    m_pLeftCamera.gameObject.SetActive(true);
                    m_pRightCamera.gameObject.SetActive(true);
                    m_bLeftCameraInLeft = false;
                    SetCameraView(true, m_bLeftCameraInLeft);
                    SetCameraActive(true, true);
                    SetCameraActive(false, true);
                    m_pMainCamera.transform.gameObject.SetActive(false);
                    //检查是否有部队团灭
                    bool leftAllDead = false;
                    if (m_lisLeftChargeTroops.Count > 0)
                    {
                        bool allDead = true;
                        for (int i = 0; i < m_lisLeftChargeTroops.Count; i++)
                        {
                            allDead = allDead && m_lisLeftChargeTroops[i].IsAllDead();
                        }
                        leftAllDead = allDead;
                    }

                    bool RightAllDead = false;
                    if (m_lisRightChargeTroops.Count > 0)
                    {
                        bool allDead = true;
                        for (int i = 0; i < m_lisRightChargeTroops.Count; i++)
                        {
                            allDead = allDead && m_lisRightChargeTroops[i].IsAllDead();
                        }
                        RightAllDead = allDead;
                    }
                    if (leftAllDead && RightAllDead)
                    {
                        //近程兵的死亡状况不用检测 有地方统一刷新
                        //StepEnterRetreat();
                    }
                    else
                    {
                        if (!leftAllDead)
                        {
                            m_lisLeftChargeTroops = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, true);
                        }
                        else
                        {
                            m_lisLeftChargeTroops.Clear();
                        }
                        if (!RightAllDead)
                        {
                            m_lisRightChargeTroops = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, false);
                        }
                        else
                        {
                            m_lisRightChargeTroops.Clear();
                        }
                        //m_pLeftCamera.gameObject.SetActive(true);
                        //m_pRightCamera.gameObject.SetActive(true);
                        m_pLeftCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(m_lisLeftChargeTroops));
                        m_pRightCameraParent.transform.position = ConvertTroop2Camera(GetTroopsCenter(m_lisRightChargeTroops));
                        SetCameraActive(true, m_lisLeftChargeTroops.Count > 0);
                        SetCameraActive(false, m_lisRightChargeTroops.Count > 0);
                        //m_pLeftCameraParent.gameObject.SetActive(m_lisLeftChargeTroops.Count > 0);
                        //m_pRightCameraParent.gameObject.SetActive(m_lisRightChargeTroops.Count > 0);

                        SetTroopMaxMoveSpeed(true, new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, SlgFightDef.FChangeSpeedMax);
                        SetTroopMaxMoveSpeed(false, new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, SlgFightDef.FChangeSpeedMax);
                    }

                }, SlgFightDef.FDelayCloseMainCamera);
            }
        }
    }

    private void CheckChargeSlowDown()
    {

    }

    private void CheckEnterRetreat()
    {
        if (m_lisShortRangeTroops.Count > 0)
        {
            m_bAllShortRangeDead = true;
            //有步兵
            for (int i = 0; i < m_lisShortRangeTroops.Count; i++)
            {
                m_bAllShortRangeDead = m_bAllShortRangeDead && m_lisShortRangeTroops[i].IsAllDead();
            }
            if (m_bAllShortRangeDead)
            {
                StepEnterRetreat();
            }
        }
    }

    private void StepEnterRetreat()
    {
        m_FlowState = Flow.Retreat;

        List<SlgEntityTroop> loserTroops = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, !m_bLeftWin);

        for (int i = 0; i < loserTroops.Count; i++)
        {
            List<SlgEntitySoldier> soldiers = loserTroops[i].GetAliveSoldier();
            for (int j = 0; j < soldiers.Count; j++)
            {
                soldiers[j].ChangeState(SlgSoldierState.c_sSoldier_Move, soldiers[j].GetBackDir());
            }
        }

        AddTimer(() =>
        {
            HeroBattleLua.C2Lua_FreshScreen(1);
        }, SlgFightDef.FRetreatDelay);

        AddTimer(() => 
        {
            SetCameraActive(true, true);
            SetCameraActive(false, false);
            Vector3 heroPos = GetTroopHeroPos(m_bLeftWin);
            m_pLeftCameraParent.transform.position = ConvertTroop2Camera(new Vector3(heroPos.x + (m_bLeftWin ? SlgFightDef.FStartBetweenHero : -SlgFightDef.FStartBetweenHero),
                                                                               heroPos.y, heroPos.z));


            List<SlgEntityTroop> winTroop = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_Arrow,
                                        SlgFightDef.c_iArmyType_batman,
                                        SlgFightDef.c_iArmyType_Knight,
                                        SlgFightDef.c_iArmyType_Tank }, m_bLeftWin);

            for (int i = 0; i < winTroop.Count; i++)
            {
                List<SlgEntitySoldier> soldiers = winTroop[i].GetAliveSoldier();
                for (int j = 0; j < soldiers.Count; j++)
                {
                    soldiers[j].ChangeState(SlgSoldierState.c_sSolider_Action, SlgFightDef.c_sAction_Skill, true);
                    soldiers[j].m_pMoveComp.StopMove();
                }
            }

            List<SlgEntityHero> heros = GetSideHero(m_bLeftWin);
            for (int i = 0; i < heros.Count; i++)
            {
                heros[i].ChangeState(SlgHeroState.c_sSlgHero_Win);
            }

        }, 0.5f + SlgFightDef.FRetreatDelay);

        AddTimer(() => 
        {
            StepEnterOver();
        }, SlgFightDef.FRetreatDelay+0.5f+2);
    }
    private void StepEnterOver()
    {
        Debug.Log("Over");
        m_FlowState = Flow.Over;
        SetCameraView(false);

        //m_fSpeed = 0;
        HeroBattleLua.C2Lua_ShowOverUI();
    }
    #endregion

    #region 美术资源模块管理
    //英雄Spine资源
    public Dictionary<string, GameObject> m_DicSpines = new Dictionary<string, GameObject>();
    //3D模型资源
    public Dictionary<string, GameObject> m_DicModel = new Dictionary<string, GameObject>();
    //所有的特效资源
    public Dictionary<string, GameObject> m_DicEffect = new Dictionary<string, GameObject>();
    //预加载的信息
    public Dictionary<string, PoolLoad> m_DicPoolPreLoad = new Dictionary<string, PoolLoad>();

    //还没开始加载的状态
    public const int m_iNotReadyLoad = -100;
    //需要加载的spine英雄模型总数
    public int m_iSpineRes = 0;
    //需要加载的特效总数
    public int m_iEffectRes = 0;
    //需要加载的模型总数
    public int m_iModelRes = 0;

    //加载Spine模型
    private void LoadSpine()
    {
        List<string> modelPaths = new List<string>();
        for (int i = 0; i < lis_Hero.Count; i++)
        {
            if (!modelPaths.Contains(lis_Hero[i].model))
            {
                modelPaths.Add(lis_Hero[i].model);
            }
        }
        if (m_eRenderType == SoldierRenderType.Spine)
        {
            for (int i = 0; i < lis_Soldier.Count; i++)
            {
                if (!modelPaths.Contains(lis_Soldier[i].config.model + "_Spine"))
                {
                    modelPaths.Add(lis_Soldier[i].config.model + "_Spine");
                }
            }
        }
        m_iSpineRes = modelPaths.Count;
        for (int i = 0; i < modelPaths.Count; i++)
        {
            string path = modelPaths[i];
            AEResources.Load(path, typeof(GameObject), delegate (UnityEngine.Object obj)
            {
                m_iSpineRes--;
                GameObject gObj = obj as GameObject;
                m_DicSpines.Add(modelPaths[i], gObj);
                if (m_iSpineRes == 0)
                {
                    LoadDone();
                }
            });
        }
        if (m_iSpineRes == 0)
        {
            LoadDone();
        }
    }

    //加载3D模型
    private void LoadModel()
    {
        List<string> modelPaths = new List<string>();
        if (m_eRenderType == SoldierRenderType.Model)
        {
            for (int i = 0; i < lis_Soldier.Count; i++)
            {
                if (!modelPaths.Contains(lis_Soldier[i].config.model + "_3D"))
                {
                    modelPaths.Add(lis_Soldier[i].config.model + "_3D");
                }
            }
        }
        m_iModelRes = modelPaths.Count;
        for (int i = 0; i < modelPaths.Count; i++)
        {
            string path = modelPaths[i];
            AEResources.Load(path, typeof(GameObject), delegate (UnityEngine.Object obj)
            {
                m_iModelRes--;
                GameObject gObj = obj as GameObject;
                m_DicModel.Add(modelPaths[i], gObj);
                if (m_iModelRes == 0)
                {
                    LoadDone();
                }
            });
        }
        if (m_iModelRes == 0)
        {
            LoadDone();
        }
    }

    //加载特效
    private void LoadEffect()
    {
        m_iEffectRes = 0;
        List<string> effPaths = new List<string>();
        effPaths.Add(GetEffPath(8001));
        effPaths.Add(GetEffPath(9001));
        effPaths.Add(GetEffPath(10001));
        effPaths.Add(GetEffPath(11001));
        effPaths.Add(GetEffPath(11002));
        effPaths.Add(GetEffPath(11003));
        effPaths.Add(GetEffPath(11004));

        List<int> entityAction = new List<int> { 11002 };
        List<SlgEntityTroop> leftRunTroops = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, true);
        List<SlgEntityTroop> rightRunTroops = GetArmyTypeTroop(new List<int>() { SlgFightDef.c_iArmyType_batman, SlgFightDef.c_iArmyType_Knight }, false);

        for (int i = 0; i < entityAction.Count; i++)
        {
            string path = GetEffPath(entityAction[i]);
            if (!m_DicPoolPreLoad.ContainsKey(path))
            {
                PoolLoad poolLoad = new PoolLoad();
                poolLoad.m_strPoolName = SlgFightDef.c_strEffPoolName;
                poolLoad.m_strPath = path;
                poolLoad.m_strPrefabName = path.Substring(path.LastIndexOf('/') + 1, path.Length - (path.LastIndexOf('/') + 1));
                poolLoad.m_iPreLoadNum = SlgFightDef.c_iMaxUnitNum * 4;
                m_DicPoolPreLoad.Add(path, poolLoad);
            }
        }

        List<int> arrow = new List<int>() { 8001,9001,10001,11003};
        for (int i = 0; i < arrow.Count; i++)
        {
            string path = GetEffPath(arrow[i]);
            if (!m_DicPoolPreLoad.ContainsKey(path))
            {
                PoolLoad poolLoad = new PoolLoad();
                poolLoad.m_strPoolName = SlgFightDef.c_strEffPoolName;
                poolLoad.m_strPath = path;
                poolLoad.m_strPrefabName = path.Substring(path.LastIndexOf('/') + 1, path.Length - (path.LastIndexOf('/') + 1));
                poolLoad.m_iPreLoadNum = SlgFightDef.IArrowShootDownNum;
                m_DicPoolPreLoad.Add(path, poolLoad);
            }
        }

        for (int i = 0; i < lis_DoBuff.Count; i++)
        {
            foreach (var item in lis_DoBuff[i].bufs.Values)
            {
                for (int j = 0; j < item.bufIds.Count; j++)
                {
                    SkillEffect skillEff = ConfigManager.Instance.SkillEffectLoader.GetInfoById(item.bufIds[j]);
                    string path = GetEffPath(skillEff.heroBatEffectId);
                    if (!effPaths.Contains(path))
                    {
                        effPaths.Add(path);
                    }
                    if (!m_DicPoolPreLoad.ContainsKey(path))
                    {
                        PoolLoad poolLoad = new PoolLoad();
                        poolLoad.m_strPoolName = SlgFightDef.c_strEffPoolName;
                        poolLoad.m_strPath = path;
                        poolLoad.m_strPrefabName = path.Substring(path.LastIndexOf('/') + 1, path.Length - (path.LastIndexOf('/') + 1));
                        poolLoad.m_iPreLoadNum = (skillEff.heroBatEffType == SlgFightDef.c_iHeroEffType_Unit) ? SlgFightDef.c_iMaxUnitNum : 1;
                        m_DicPoolPreLoad.Add(path, poolLoad);
                    }
                }
            }
        }

        m_iEffectRes = effPaths.Count;
        for (int i = 0; i < effPaths.Count; i++)
        {
            string path = effPaths[i];
            AEResources.Load(path, typeof(GameObject), delegate (UnityEngine.Object obj)
            {
                m_iEffectRes--;
                GameObject gObj = obj as GameObject;
                m_DicEffect.Add(effPaths[i], gObj);
                if (m_iEffectRes == 0)
                {
                    LoadDone();
                }
            });
        }
        if (m_iEffectRes == 0)
        {
            LoadDone();
        }
    }
    private string GetEffPath(int effId)
    {
        if (effId != 0)
        {
            HeroEff config = ConfigManager.Instance.heroEffLoader.GetInfoById(effId);
            if (config != null)
            {
                return config.path;
            }
        }

        return null;
    }

    private void LoadDone()
    {
        if (m_iEffectRes == 0 && m_iEffectRes != m_iNotReadyLoad &&
            m_iSpineRes == 0 && m_iSpineRes != m_iNotReadyLoad &&
            m_iModelRes == 0 && m_iModelRes != m_iNotReadyLoad)
        {
            m_iEffectRes = m_iNotReadyLoad;
            m_iSpineRes = m_iNotReadyLoad;
            m_iModelRes = m_iNotReadyLoad;
            
            //对象池子
            StartCoroutine(InitPool());
        }
    }

    private IEnumerator InitPool()
    {
        int waitFrame = 0;
        foreach (var item in m_DicPoolPreLoad.Values)
        {
            if (!PoolManager.Pools.ContainsKey(item.m_strPoolName))
            {
                PoolManager.Pools.Create(item.m_strPoolName);
            }
            SpawnPool pool = PoolManager.Pools[item.m_strPoolName];
            PrefabPool prefabPool = new PrefabPool(m_DicEffect[item.m_strPath].transform);
            prefabPool.preloadAmount = item.m_iPreLoadNum;
            prefabPool.cullDespawned = false;
            prefabPool.preloadTime = true;
            prefabPool.preloadFrames = (item.m_iPreLoadNum / SlgFightDef.c_iFrameLoadObjNum) + 1;
            waitFrame += prefabPool.preloadFrames;
            pool.CreatePrefabPool(prefabPool);
        }
        waitFrame++;
        while (waitFrame > 0)
        {
            yield return null;
            waitFrame--;
        }
        //创建英雄
        CreateHero();
        CreateTroop();
        InitDmg();
        if (m_funcLoadDone != null)
        {
            m_funcLoadDone();
        }
    }
    #endregion


    //--------------重复的部分  之后重构到一起------------
    public bool m_bPause = false;
    private float m_fSpeed = 1;
    public float Speed
    {
        get { return m_fSpeed; }
    }
    private double m_dPassTime = 0;
    public double PassTime
    {
        get { return m_dPassTime; }
    }
    public float DeltaTime
    {
        get { return m_fSpeed * Time.deltaTime; }
    }

    private Action m_funcLoadDone;

    protected virtual void Update()
    {
        if (!m_bInit)
            return;

        BattleEntityFactory.Instance.OnUpdate(m_fSpeed * Time.deltaTime);
        UpTimer(m_fSpeed * Time.deltaTime);
        BattleEffectMgr.Instance.OnUpdate(m_fSpeed * Time.deltaTime);
        EntityMessageDispatcher.Instance.OnUpdate(m_fSpeed * Time.deltaTime);
        OnUpdateCameraPart(m_fSpeed * Time.deltaTime);

        m_dPassTime += m_fSpeed * Time.deltaTime;

        //if (Input.GetKeyDown(KeyCode.S))
        //{
        //    AllTroopMove();
        //}
        if (Input.GetKeyDown(KeyCode.F))
        {
            m_lisTroops[0].RandomDeadByNum(1, true);
        }
        if (Input.GetKeyDown(KeyCode.G))
        {
            //DKLuaUtil.ShakeTransform(m_pLeftCamera.transform);
            //StepEnterReviewTroops(true);
            StepEnterReviewTroops2(true);
            //StepEnterShooterAtk();
            //StepEnterCharge();
        }

        if (Input.GetKeyDown(KeyCode.H))
        {
            Reload();
        }
        if (Input.GetKeyDown(KeyCode.J))
        {
            StepEnterCharge();
        }

        if (Input.GetKeyDown(KeyCode.K))
        {
            m_pLeftCameraParent.transform.position = ConvertTroop2Camera(GetTroopSidePos(false, true));
        }
        if (Input.GetKeyDown(KeyCode.L))
        {
            m_pLeftCameraParent.transform.position = ConvertTroop2Camera(GetTroopSidePos(false,false));
        }

        if (Input.GetKeyDown(KeyCode.M))
        {
            HeroBattleLua.C2Lua_StartUIAni();
        }

        if (Input.GetKeyDown(KeyCode.Z))
        {
            //HeroBattleLua.C2Lua_SuiPingFX();
            SlgEntitySoldier soldier = m_lisTroops[0].GetAliveSoldier()[0];
            soldier.m_bDead = true;
            soldier.PlayAction(SlgFightDef.c_sAction_Dead, false);
            soldier.m_pMoveComp.UniformMove(10, m_pMainCamera.transform.position + m_pMainCamera.transform.forward * 1.5f);
            float t = soldier.m_pMoveComp.GetRemainingTime();
            AddTimer(() => 
            {
                soldier.m_pGameObj.SetActive(false);
                HeroBattleLua.C2Lua_SuiPingFX(m_pMainCamera.transform.localEulerAngles, SlgBattleMgr.Instance.gameObject.transform,soldier.m_pGameObj.transform.position);
            }, t);
        }
    }

    #region 统一管理带时间缩放的逻辑计时器
    //逻辑计时器
    private int m_iTimerId = 100;
    List<TimerVo> m_lisTimer = new List<TimerVo>();
    List<TimerVo> m_lisAdder = new List<TimerVo>();
    List<TimerVo> m_lisRemoveIds = new List<TimerVo>();


    private void UpTimer(float deltaTime)
    {
        if (m_lisAdder.Count > 0)
        {
            for (int i = 0; i < m_lisAdder.Count; i++)
            {
                m_lisTimer.Add(m_lisAdder[i]);
            }
            m_lisAdder.Clear();
        }

        for (int i = 0; i < m_lisTimer.Count; i++)
        {
            m_lisTimer[i].passTime += deltaTime;
            if (m_lisTimer[i].passTime >= m_lisTimer[i].duration)
            {
                m_lisTimer[i].action();
                m_lisRemoveIds.Add(m_lisTimer[i]);
            }
        }
        if (m_lisRemoveIds.Count > 0)
        {
            for (int i = 0; i < m_lisRemoveIds.Count; i++)
            {
                //Debug.LogFormat("Timer-删除 : {0}", m_lisRemoveIds[i].ToString());
                m_lisTimer.Remove(m_lisRemoveIds[i]);
            }
            m_lisRemoveIds.Clear();
        }
    }
    public int AddTimer(Action action, float delay, string toString = "")
    {
        m_iTimerId++;
        TimerVo vo = new TimerVo(m_iTimerId, action, delay, toString);
        m_lisAdder.Add(vo);
        return vo.id;
    }
    public void DelTimer(int id)
    {
        for (int i = 0; i < m_lisTimer.Count; i++)
        {
            if (m_lisTimer[i].id == id &&
               !m_lisRemoveIds.Contains(m_lisTimer[i]))
            {
                m_lisRemoveIds.Add(m_lisTimer[i]);
            }
        }
    }
    public void DelAllTimer()
    {
        for (int i = 0; i < m_lisTimer.Count; i++)
        {
            DelTimer(m_lisTimer[i].id);
        }
        for (int i = 0; i < m_lisAdder.Count; i++)
        {
            DelTimer(m_lisAdder[i].id);
        }
    }
    public class TimerVo
    {
        public int id;//终止清除
        public Action action;
        public float duration;
        public float passTime;
        public string toString;

        public TimerVo(int id, Action action, float duration, string toString)
        {
            this.id = id;
            this.action = action;
            this.duration = duration;
            this.toString = toString;
            passTime = 0;
        }

        public override string ToString()
        {
            return toString;
        }
    }
    #endregion
}

public class SoldierVo
{
    public int pId;
    public int pos;
    public int hp;
    public bool m_bleft;
    public int beforeHp;
    public int afterHp;
    public SoliderInfo config;
}

public class TroopDmg
{
    public int attackTroopId;
    public int defTroopId;
    public int dmg;
    public bool done;
}

public class DoBuff
{
    public int doPos;
    public int skillId;
    public Dictionary<int,BufVo> bufs;
}

public class BufVo
{
    public int defPos;
    public List<int> bufIds;
}

public class PoolLoad
{
    public string m_strPoolName;
    public string m_strPath;
    public string m_strPrefabName;
    public int m_iPreLoadNum;
}